import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;

public class TestJFrame extends JFrame {
    private JLabel open, create, rename, delete;
    private JLabel info, confirm, close, select;
    private JTextField bigTextField;
    private JTextField nameText;
    private JLabel[][] fileLabels;
    private JTextField[][] textFields;
    private ArrayList<MyFile> files;
    private boolean infoIsOpened, dotIsLeft;
    private int selectedIndex = -1;

    private TestJFrame() {
        super("文件操作");
        this.setSize(1200, 930);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        ImageIcon img = new ImageIcon("images/背景.jpg");//这是背景图片
        JLabel imgLabel = new JLabel(img);//将背景图放在标签里。
        this.getLayeredPane().add(imgLabel, new Integer(Integer.MIN_VALUE));//背景标签添加
        imgLabel.setBounds(0, 0, img.getIconWidth(), img.getIconHeight());//设置背景标签的位置
        Container cp = this.getContentPane();
        cp.setLayout(null);
        ((JPanel) cp).setOpaque(false); //注意这里，将内容面板设为透明

        /*
         * 这边是创建文件夹的淡出窗口
         * */
        infoIsOpened = false;//默认关闭
        dotIsLeft = false;//默认选择右边

        nameText = new JTextField();
        nameText.setBounds(525, 395, 150, 35);
        beautifyTextField(nameText);
        nameText.setForeground(Color.black);
        nameText.setEnabled(true);
        nameText.setVisible(false);
        cp.add(nameText);

        close = new JLabel(new ImageIcon("images/X.png"));
        close.setBounds(650, 350, 22, 17);
        close.setVisible(false);
        cp.add(close);

        select = new JLabel(new ImageIcon("images/圆点文本文件.png"));
        select.setBounds(510, 505, 177, 25);
        select.setVisible(false);
        cp.add(select);

        confirm = new JLabel(new ImageIcon("images/确定.png"));
        confirm.setBounds(477, 550, 154, 35);
        confirm.setVisible(false);
        cp.add(confirm);

        info = new JLabel(new ImageIcon("images/信息.png"));
        info.setBounds(400, 330, 300, 300);
        info.setVisible(false);
        cp.add(info);

        //用于分隔开弹出窗口和内容
        bigTextField = new JTextField();
        bigTextField.setBounds(0, 0, 1200, 900);
        beautifyTextField(bigTextField);
        bigTextField.setVisible(false);
        cp.add(bigTextField);

        /*
         * 下面是主体内容
         * */

        //三行四列的文件存放位置
        fileLabels = new JLabel[3][4];
        //容量为12
        files = new ArrayList<>(12);
        File filePath = new File("./fileInfo.txt");
        if (filePath.exists())
            files = (ArrayList<MyFile>) read("./fileInfo.txt");
        textFields = new JTextField[3][4];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                String str = "" + (4 * i + j);
                fileLabels[i][j] = new JLabel(new ImageIcon("images/位置.png"));
                fileLabels[i][j].setName(str);
                fileLabels[i][j].setBounds(240 + j * 200, 300 + 200 * i, 120, 120);
                textFields[i][j] = new JTextField();
                textFields[i][j].setBounds(240 + j * 200, 420 + 200 * i, 120, 25);
                beautifyTextField(textFields[i][j]);
                cp.add(fileLabels[i][j]);
                cp.add(textFields[i][j]);
            }
        }

        open = new JLabel(new ImageIcon("images/打开.png"));
        open.setBounds(240, 50, 120, 120);
        cp.add(open);

        create = new JLabel(new ImageIcon("images/新建.png"));
        create.setBounds(440, 50, 120, 120);
        cp.add(create);

        rename = new JLabel(new ImageIcon("images/重命名.png"));
        rename.setBounds(640, 50, 120, 120);
        cp.add(rename);

        delete = new JLabel(new ImageIcon("images/删除.png"));
        delete.setBounds(840, 50, 120, 120);
        cp.add(delete);

        update();

        create.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                infoSwitch();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                create.setIcon(new ImageIcon("images/新建_选中.png"));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                create.setIcon(new ImageIcon("images/新建.png"));
            }
        });

        open.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                String str = "./fileRoot/";
                if (files.get(selectedIndex).getType().equals("文本文件"))
                    str += files.get(selectedIndex).getName() + ".txt";
                else
                    str += files.get(selectedIndex).getName();
                File file = new File(str);
                try {
                    Desktop.getDesktop().open(file);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                open.setIcon(new ImageIcon("images/打开_选中.png"));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                open.setIcon(new ImageIcon("images/打开.png"));
            }
        });

        rename.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (selectedIndex != -1) {
                    textFields[selectedIndex / 4][selectedIndex % 4].setText("");
                    textFields[selectedIndex / 4][selectedIndex % 4].setEnabled(true);
                    textFields[selectedIndex / 4][selectedIndex % 4].requestFocus(true);
                    /*
                     * 先把原来的文件删除，然后按下回车的时候重新创建一个文件
                     * */
                    String str = "./fileRoot/";
                    if (files.get(selectedIndex).getType().equals("文本文件"))
                        str += files.get(selectedIndex).getName() + ".txt";
                    else
                        str += files.get(selectedIndex).getName();
                    File file = new File(str);
                    if (file.exists()) {
                        file.delete();
                    }
                } else
                    JOptionPane.showMessageDialog(null, "未选中任何文件！");

            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                rename.setIcon(new ImageIcon("images/重命名_选中.png"));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                rename.setIcon(new ImageIcon("images/重命名.png"));
            }
        });

        delete.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                String str = "./fileRoot/";
                if (files.get(selectedIndex).getType().equals("文本文件"))
                    str += files.get(selectedIndex).getName() + ".txt";
                else
                    str += files.get(selectedIndex).getName();
                File file = new File(str);
                if (file.exists()) {
                    file.delete();
                    files.remove(selectedIndex);
                    write(files, filePath.getName());
                    JOptionPane.showMessageDialog(null, "    删除成功！");
                    selectedIndex = -1;
                    update();
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                delete.setIcon(new ImageIcon("images/删除_选中.png"));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                delete.setIcon(new ImageIcon("images/删除.png"));
            }
        });

        close.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                infoSwitch();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                close.setIcon(new ImageIcon("images/X1.png"));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                close.setIcon(new ImageIcon("images/X.png"));
            }
        });
        confirm.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                if (dotIsLeft) {
                    if (nameText.getText().length() == 0 || nameText.getText().charAt(0) == ' ')
                        JOptionPane.showMessageDialog(null, "名字不符合规范！");
                    else if (files.size() < 12) {
                        createFileBag(nameText.getText());

                        MyFile file = new MyFile();
                        file.setName(nameText.getText());
                        file.setType("文件夹");
                        file.setParent("fileRoot");
                        //如果文件名不重复
                        if (judgeName(nameText.getText(), "文件夹")) {
                            files.add(file);
                            write(files, filePath.getName());
                            update();//更新视图
                        } else
                            JOptionPane.showMessageDialog(null, "文件名重复！\n    创建失败！");
                    } else
                        JOptionPane.showMessageDialog(null, "超过最大容量！\n    创建失败！");

                } else {
                    if (nameText.getText().length() == 0 || nameText.getText().charAt(0) == ' ')
                        JOptionPane.showMessageDialog(null, "名字不符合规范！");
                    else if (files.size() < 12) {
                        createTextFile(nameText.getText());
                        MyFile file = new MyFile();
                        file.setName(nameText.getText());
                        file.setType("文本文件");
                        file.setParent("fileRoot");
                        //如果文件名不重复
                        if (judgeName(nameText.getText(), "文本文件")) {
                            files.add(file);
                            write(files, filePath.getName());
                            update();//更新视图
                        } else
                            JOptionPane.showMessageDialog(null, "文件名重复！\n    创建失败！");
                    } else
                        JOptionPane.showMessageDialog(null, "超过最大容量！\n    创建失败！");
                }
                infoSwitch();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                confirm.setIcon(new ImageIcon("images/确定1.png"));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                confirm.setIcon(new ImageIcon("images/确定.png"));
            }
        });
        select.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                if (!dotIsLeft) {
                    select.setIcon(new ImageIcon("images/圆点文件夹.png"));
                    dotIsLeft = true;
                } else {
                    select.setIcon(new ImageIcon("images/圆点文本文件.png"));
                    dotIsLeft = false;
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                fileLabels[i][j].addMouseListener(new fileClickListener());
//                fileLabels[i][j].addMouseMotionListener(new fileMotionListener());
                textFields[i][j].addKeyListener(new textKeyListener());
            }
        }
        this.setName("-1");
        this.addMouseListener(new fileClickListener());
        this.setVisible(true);
    }

    /**
     * 更新视图
     */
    private void update() {
        int len1 = files.size() / 4;
        int len2 = files.size() % 4;
        //先清空一下，再加载
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                fileLabels[i][j].setIcon(new ImageIcon("images/位置.png"));
                textFields[i][j].setText("");
            }
        }
        //前面len1行
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < 4; j++) {
                if (files.get(i * 4 + j).getType().equals("文件夹")) {
                    fileLabels[i][j].setIcon(new ImageIcon("images/空文件夹.png"));
                    textFields[i][j].setText(files.get(i * 4 + j).getName());
                } else {
                    fileLabels[i][j].setIcon(new ImageIcon("images/文本.png"));
                    textFields[i][j].setText(files.get(i * 4 + j).getName());
                }
            }
        }
        //最后一行
        for (int i = 0; i < len2; i++) {
            if (files.get(len1 * 4 + i).getType().equals("文件夹")) {
                fileLabels[len1][i].setIcon(new ImageIcon("images/空文件夹.png"));
                textFields[len1][i].setText(files.get(len1 * 4 + i).getName());
            } else {
                fileLabels[len1][i].setIcon(new ImageIcon("images/文本.png"));
                textFields[len1][i].setText(files.get(len1 * 4 + i).getName());
            }
        }
    }

    /**
     * 创建文件夹
     */
    private void createFileBag(String fileName) {
        //创建根目录
        File fileRoot = new File("./fileRoot");
        if (!fileRoot.exists()) {
            fileRoot.mkdirs();
        }
        if (fileName.length() > 0 && fileName.charAt(0) != ' ') {
            //在这个根目录下创建一个新的文件夹
            File file = new File("./fileRoot/" + fileName);
            if (!file.exists()) {
                file.mkdirs();
            }
        } else {
            System.out.println("文件名字不符合规范");
        }
    }

    private boolean judgeName(String name, String type) {
        for (MyFile file : files) {
            if (file.getName().equals(name) && file.getType().equals(type))
                return false;
        }
        return true;
    }

    /**
     * 创建文本文件(指定父目录)
     */
    private void createTextFile(String parentFileName, String fileName) {
        //创建根目录
        File fileRoot = new File("./fileRoot");
        if (!fileRoot.exists()) {
            fileRoot.mkdirs();
        }
        if (fileName.length() > 0 && fileName.charAt(0) != ' ') {
            //在这个根目录下创建一个新的文件
            File file = new File("./fileRoot/" + parentFileName + "/" + fileName + ".txt");
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter(file));
                bw.write("文件创建成功！");
                bw.close();//一定要关闭文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("文件名字不符合规范");
        }
    }

    /**
     * 创建文本文件(无父目录，直接在根目录创建文件)
     */
    private void createTextFile(String fileName) {
        //创建根目录
        File fileRoot = new File("./fileRoot");
        if (!fileRoot.exists()) {
            fileRoot.mkdirs();
        }
        if (fileName.length() > 0 && fileName.charAt(0) != ' ') {
            //在这个根目录下创建一个新的文件
            File file = new File("./fileRoot/" + fileName + ".txt");
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter(file));
                bw.write("文件创建成功！");
                bw.close();//一定要关闭文件
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("文件名字不符合规范");
        }
    }

    private void infoSwitch() {
        if (!infoIsOpened) {
            info.setVisible(true);
            confirm.setVisible(true);
            close.setVisible(true);
            select.setVisible(true);
            nameText.setVisible(true);
            bigTextField.setVisible(true);
            nameText.requestFocus(true);
            infoIsOpened = true;
        } else {
            info.setVisible(false);
            confirm.setVisible(false);
            close.setVisible(false);
            select.setVisible(false);
            nameText.setVisible(false);
            nameText.setText("");//清空
            bigTextField.setVisible(false);
            infoIsOpened = false;
        }
    }

    /*
     * 文本框美化方法复用
     * */
    private void beautifyTextField(JTextField jTextfield) {
        jTextfield.setOpaque(false);
        jTextfield.setHorizontalAlignment(JTextField.CENTER);
        jTextfield.setForeground(Color.white);
        jTextfield.setFont(new Font("黑体", Font.PLAIN, 20));
        jTextfield.setBorder(new LineBorder(null, 0));
        jTextfield.setEnabled(false);
    }

    /**
     * 读文件
     */
    private static Object read(String fileName) {
        Object temp = null;
        File file = new File(fileName);
        try {
            FileInputStream in = new FileInputStream(file);//文件字节输入流
            ObjectInputStream objIn = new ObjectInputStream(in);//对象字节输入流
            temp = objIn.readObject();
            objIn.close();
            System.out.println("载入文件成功!");
        } catch (Exception e) {
            System.out.println("载入文件失败!");
        }
        return temp;
    }

    /**
     * 写文件
     */
    private static void write(Object obj, String fileName) {
        File file = new File(fileName);
        try {
            FileOutputStream out = new FileOutputStream(file);//文件字节输出流
            ObjectOutputStream objOut = new ObjectOutputStream(out);//对象字节输出流
            objOut.writeObject(obj);
            objOut.close();
            System.out.println("写入成功!");
        } catch (Exception e) {
            System.out.println("写入失败");
        }
    }

    /**
     * 文件点击监听器的内部类
     */
    class fileClickListener implements MouseListener {
        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
            selectedIndex = Integer.parseInt(e.getComponent().getName());
            for (int i = 0; i < files.size(); i++) {
                if (selectedIndex == i && files.get(i).getType().equals("文件夹")) {
                    update();
                    fileLabels[i / 4][i % 4].setIcon(new ImageIcon("images/空文件夹_选中.png"));
                    break;
                } else if (selectedIndex == i && files.get(i).getType().equals("文本文件")) {
                    update();
                    fileLabels[i / 4][i % 4].setIcon(new ImageIcon("images/文本_选中.png"));
                    break;
                } else
                    update();

            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    }

    /**
     * 文件拖拽事件监听器的内部类
     */
    class fileMotionListener implements MouseMotionListener {
        @Override
        public void mouseDragged(MouseEvent e) {
            selectedIndex = Integer.parseInt(e.getComponent().getName());
            Point position = getMousePosition();
            Insets insets = getInsets();
            if (selectedIndex >= 0 && selectedIndex < files.size()) {
                e.getComponent().setLocation(position.x - insets.left - 60, position.y - insets.top - 60);
                textFields[selectedIndex / 4][selectedIndex % 4].setLocation(position.x - insets.left - 60, position.y - insets.top + 60);
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
        }
    }

    /**
     * 文本焦点事件监听器的内部类
     */
    class textKeyListener implements KeyListener {
        @Override
        public void keyTyped(KeyEvent e) {
            if (e.getKeyChar() == '\n') {
                textFields[selectedIndex / 4][selectedIndex % 4].setEnabled(false);
                files.get(selectedIndex).setName(textFields[selectedIndex / 4][selectedIndex % 4].getText());
                /*
                 * 新的文件名
                 * */
                File file;
                if (files.get(selectedIndex).getType().equals("文本文件")) {
                    file = new File("./fileRoot/" + files.get(selectedIndex).getName() + ".txt");
                    try {
                        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
                        bw.write("文件名修改成功！");
                        bw.close();//一定要关闭文件
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                } else {
                    file = new File("./fileRoot/" + files.get(selectedIndex).getName());
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                }
                write(files, "./fileInfo.txt");
                update();
                selectedIndex = -1;
            }
        }

        @Override
        public void keyPressed(KeyEvent e) {
        }

        @Override
        public void keyReleased(KeyEvent e) {
        }
    }


    public static void main(String[] args) {
        new TestJFrame();
    }
}
